package com.ironman.imes.device.data.source.listener;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ironman.imes.device.data.source.verticles.HttpServerVerticle;
import com.ironman.imes.device.data.source.verticles.MqttClientVerticle;
import com.ironman.imes.device.framework.orm.db1.SourceInfoMapper;
import com.ironman.imes.device.framework.orm.db1.dataobject.SourceInfo;
import com.ironman.imes.device.framework.orm.enums.EnableEnum;
import io.vertx.core.Vertx;
import io.vertx.core.VertxOptions;
import io.vertx.core.impl.cpu.CpuCoreSensor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.noear.snack.ONode;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Component
@RequiredArgsConstructor
public class DeviceDataSourceAppReadyEventListener implements ApplicationListener<ApplicationReadyEvent> {

    final SourceInfoMapper sourceInfoMapper;

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        List<SourceInfo> sourceInfos = sourceInfoMapper.selectList(Wrappers.lambdaQuery(SourceInfo.class)
                .select(SourceInfo::getType, SourceInfo::getConfig)
                .eq(SourceInfo::getEnable, EnableEnum.ENABLE));
        Vertx vertx = Vertx.vertx(new VertxOptions()
                .setEventLoopPoolSize(CpuCoreSensor.availableProcessors()));
        for (SourceInfo sourceInfo : sourceInfos) {
            String configStr = sourceInfo.getConfig();
            List<ONode> configNodeList = ONode.loadStr(configStr).ary();
            switch (sourceInfo.getType()) {
                case "http":
                    for (ONode configNode : configNodeList) {
                        String name = configNode.get("name").getString();
                        ONode config = configNode.get("config");
                        String host = config.get("host").getString();
                        int port = config.get("port").getInt();
                        List<ONode> api = config.get("api").ary();
                        vertx.deployVerticle(new HttpServerVerticle(name, host, port, api))
                                .onSuccess(id -> {
                                    log.info("HTTP服务启动成功 {} {}", port, id);
                                }).onFailure(throwable -> {
                                    log.error("HTTP服务启动失败, {}", throwable.getMessage());
                                });
                    }
                    break;
                case "mqtt":
                    for (ONode configNode : configNodeList) {
                        String name = configNode.get("name").getString();
                        ONode config = configNode.get("config");
                        String host = config.get("host").getString();
                        int port = config.get("port").getInt();
                        String clientIdPrefix = config.get("clientIdPrefix").getString();
                        String username = config.get("username").getString();
                        String password = config.get("password").getString();
                        boolean cleanSession = config.get("cleanSession").getBoolean();
                        int keepAliveInterval = config.get("keepAliveInterval").getInt();
                        List<ONode> topics = config.get("topics").ary();
                        vertx.deployVerticle(new MqttClientVerticle(name, host, port, clientIdPrefix, username, password, cleanSession, keepAliveInterval, topics));
                    }
                    break;
                default:
                    break;
            }
        }
    }
}